#include "Cliente.h"
#include <libxml/parser.h>  /*trabaja con los ficheros xml*/
#include <libxml/tree.h>    /*trabaja con el árbol generado de parsear el xml*/
#include "../SOAP/DesempaquetadorSoap.h"
#include "../SOAP/empaquetadorSoap.h"

using namespace std;

int Cliente:: conectar_con_servidor(string ip,int puerto, Socket* sock){

	if(Connect((char*)ip.c_str(),puerto,sock)==-1){
		std::cerr<<"Error puerto invalido"<<std::endl;
		return 0;
	}
	else{
		std::cerr<<"Se realizado la conexion"<<std::endl;
		return 1;
	}
}


bool Cliente:: obtener_datos(std::string ip, int puerto, std::string nombreArch, int& entradas, int& salidas){
	bool resultado = true;
	Socket* sock=new Socket();
	xmlDocPtr docSoap,docEmp;
	DesempaquetadorSoap desSoap;
	empaquetadorSoap empTemp;
	if(conectar_con_servidor(ip, puerto,sock)){
		/*
		 * Le pido al servidor la informacion para dibujar
		 * la caja negra en pantalla
		 */
		std::string nombre(CIRCUITOS_PUBLICADOS);
		nombre.append(nombreArch);

		docEmp = empTemp.empaquetar_orden_a_enviar("data",nombre, "vacio");
		char * linea[10000];
		int * pi = new int(10000);
		xmlDocDumpMemory (docEmp, (xmlChar**)linea, pi);
		std::string l_cadena(*linea);


		Send((char*)l_cadena.c_str(),sock);
		std::string msj;
		int recive_return=Recive(sock,msj);
		if(recive_return >=0){
			docSoap = xmlParseMemory ((char*)msj.c_str(), msj.size());
			entradas = desSoap.obtenerEntradas(docSoap);
			salidas = desSoap.obtenerSalidas(docSoap);
		}
		else{
			cerr<<"Error al conectar con el servidor"<<endl;
			entradas = 0;
			salidas = 0;
			resultado = false;
		}

	}
	else{
		cerr<<"Error no se pudo conectar con el servidor"<<endl;
		resultado = false;
	}

	Close(sock);
	delete sock;
	return resultado;
}


char * Cliente:: mostrar_circuito(std::string ip, int puerto, std::string nombreArch){
	DesempaquetadorSoap temp;
	empaquetadorSoap empTemp;
	char* rutaArchivoTempSoap = (char*)"./SOAP/tempSoap.xml";
	char* rutaArchivoTempXml = (char*)"./SOAP/tempXml.xml";
	xmlDocPtr docSoap, docXml,docEmp;
	std::string nombre( CIRCUITOS_PUBLICADOS);
	nombre.append(nombreArch);
	Socket* sock=new Socket();
	if(conectar_con_servidor(ip, puerto, sock)){
		/*
		 * Le pido al servidor la informacion mostrar el
		 * circuito en mi pantalla
		 */
		docEmp = empTemp.empaquetar_orden_a_enviar("ver",nombre, "vacio");
		char * linea[10000];
		int * pi = new int(10000);
		xmlDocDumpMemory (docEmp, (xmlChar**)linea, pi);
		std::string l_cadena(*linea);

		Send((char*)l_cadena.c_str(),sock);
		std::string msj;
		int recive_result=Recive(sock,msj);
		if(recive_result>=0){
			docSoap = xmlParseMemory ((char*)msj.c_str(), msj.size());

			if (docSoap != NULL)
				xmlSaveFile(rutaArchivoTempSoap, docSoap);
			else{
				//en este caso no pudo guardar el archivo por que no era valido
				Close(sock);
				delete sock;
				return NULL;

			}
			//desempaqueto el temp
			docXml = temp.Desempaquetar(rutaArchivoTempSoap);
			//devuelvo la ruta del archivo creado para que la interfaz lo levante y dibuje
			if (docXml != NULL){
				xmlSaveFile(rutaArchivoTempXml, docXml);
				Close(sock);
				delete sock;
				return rutaArchivoTempXml;
			}
		}
		else{
			cerr<<"Error no se pudo conectar con el servidor"<<endl;
			return NULL;
		}
	}
	else{
		cerr<<"Error no se pudo conectar con el servidor"<<endl;
	}
	Close(sock);
	delete sock;
	return NULL;

}

std::string Cliente:: obtener_salida(std::string ip, int puerto,std::string nombreArch, std::string entradas){
	Socket* sock=new Socket();
	xmlDocPtr docSoap, docEmp;
	DesempaquetadorSoap temp;
	empaquetadorSoap empTemp;
	std::string nombre( CIRCUITOS_PUBLICADOS);
	nombre.append(nombreArch);
	if(conectar_con_servidor(ip, puerto,sock)){
		/*
		 * Le paso al servidor las entradas y me devuelve
		 * las salidas
		 */

		std:: string orden(nombre);

		docEmp = empTemp.empaquetar_orden_a_enviar("simular",nombre, entradas);
		char * linea[10000];
		int * pi = new int(10000);
		xmlDocDumpMemory (docEmp, (xmlChar**)linea, pi);
		std::string l_cadena(*linea);

		Send((char*)l_cadena.c_str(),sock);

		std::string msj;
		int recive_result= Recive(sock,msj);
		if(recive_result>=0){

			docSoap = xmlParseMemory ((char*)msj.c_str(), msj.size());
			std::string resultado = temp.obtener_simulacion(docSoap);

			Close(sock);
			delete sock;
			return resultado;

		}
	//ver q pasa cuando le das simular a un circuito no listo
		else {
			Close(sock);
			delete sock;
			return "ERROR";
		}
	}
	else{
		cerr<<"Error no se pudo conectar con el servidor"<<endl;
	}
	Close(sock);
	delete sock;
	return "ERROR";
}



//*------------------------*//
//*Metodos de Comunicacion *//
//*------------------------*//


int Cliente::Recive(Socket* sock_emisor,std::string& stream){
	return sock_emisor->recvtimeout(stream);
}

int Cliente::Send(char* msj,Socket* sock_destino){
	int len;
	len=strlen(msj);
	return(sock_destino->send(msj, len));
}

int Cliente::Close(Socket* sock){
	sock->close();
	return 0;
}

int Cliente::Connect(char* ip, int puerto,Socket* sock){
	return(sock->connect(ip, puerto));
}


